﻿#pragma once
#pragma execution_character_set("utf-8")
#ifdef BUILD_STATIC
#  define DLL_EXPORT Q_DECL_EXPORT
# else
#  define DLL_EXPORT 
//#  define DLL_EXPORT Q_DECL_IMPORT
# endif
#include <QtPlugin>
#include <qobject.h>
#include <QString>
#include <QQueue>
#include <qmutex.h>
#include <QTime>
#include <QTimer>
 namespace XIOPlug {
	typedef enum {
		opened,
		closed,
		openFail,
		closeFail
	}Status;
	typedef struct {
		QString dev;//id
		QString port;//端口
		QString des;
		QString baud;
		QString dataBits;
		QString stopBits;
		QString parity;
		QString flowControl;
	}Dev;
};
class  XIOPlugBase:public QObject
{	
	Q_OBJECT
	Q_PROPERTY(XIOPlug::Status status READ getStatus WRITE setStatus NOTIFY statusChanged)//连接状态
	Q_PROPERTY(XIOPlug::Dev dev READ getDev WRITE setDev)//设备信息
	Q_PROPERTY(uint Rnum READ getRnum WRITE setRnum)//接收帧个数
	Q_PROPERTY(uint Tnum READ getTnum WRITE setTnum)//发送帧个数
	Q_PROPERTY(uint Enum READ getEnum WRITE setEnum)//错误帧个数
	Q_PROPERTY(uint RdataSize READ getRdataSize WRITE setRdataSize)//接收数据大小
	Q_PROPERTY(uint TdataSize READ getTdataSize WRITE setTdataSize)//发送数据大小
	Q_PROPERTY(uint EdataSize READ getEdataSize WRITE setEdataSize)//错误数据大小
	//Q_PROPERTY(QList<QString> channels READ getchannels WRITE setchannels)//错误数据大小
public:

	typedef struct {
		QTime time;
		QString channel;
		QByteArray data;
	}IOStream;//接收数据帧
public:
XIOPlugBase(QObject *parent = 0);
~XIOPlugBase();
void clearBuffer();
signals:
	void readReady();//接收数据就绪信号
	void statusChanged(XIOPlug::Status,QString str = "");
	void channelChanged(QString);
	void sendIOStreamed(QList<IOStream>);
	void sendError(QList<IOStream>);
public slots:
	virtual bool openDev(XIOPlug::Dev& dev)  = 0;
	virtual void colseDev()  = 0;
	virtual	QList< IOStream> readAll();
	virtual QList< IOStream> read(const int num);
	 void Asyn_write(IOStream data);//异步发送
	 void Asyn_write(QList < IOStream> datas);
public:
	XIOPlug::Status getStatus() const  { return status; } ;
	XIOPlug::Dev getDev() const { return dev; }
	QString getPort() const { return dev.port; }
	uint getRnum() const { return Rnum; }
	uint getTnum() const { return Tnum; }
	uint getEnum() const { return Enum; }
	uint getRdataSize() const { return RdataSize; }
	uint getTdataSize() const { return TdataSize; }
	uint getEdataSize() const { return EdataSize; }
	void setStatus(XIOPlug::Status status) {
		if (status != this->status) {
			this->status = status;
			emit statusChanged(status);
		}
	};
	void setDev(XIOPlug::Dev d) { 
				dev = d;
		 }
	void setRnum(uint num) { if(Rnum != num)this->Rnum = num; }
	void setTnum(uint num) { if(Tnum != num)this->Tnum = num; }
	void setEnum(uint num) { if(Enum != num)this->Enum = num; }
	void setRdataSize(uint num) { if(RdataSize != num)this->RdataSize = num; }
	void setTdataSize(uint num) { if(TdataSize != num)this->TdataSize = num; }
	void setEdataSize(uint num) { if(EdataSize != num)this->EdataSize = num; }
	QList<QString> getchannels() const { return _channels; }
	void setchannels( QString channel, bool add = true);
protected:
	virtual void _runAPP()  = 0;
	virtual void _readSlot() = 0;

protected:
	XIOPlug::Status status;
	XIOPlug::Dev dev;
	QScopedPointer<QQueue<IOStream>> _Rdata;
	QScopedPointer<QQueue<IOStream>> _Tdata;
	uint Rnum;
	uint Tnum;
	uint Enum;
	uint RdataSize;
	uint TdataSize;
	uint EdataSize;
	QMutex _Rmutex;
	QMutex _Tmutex;
	QScopedPointer<QTimer> _timer;
	QList<QString> _channels;//通道
};
#define XIOPlugBase_iid "IO.Plugin.XIOPlugBase"   // 唯一标识符

Q_DECLARE_INTERFACE(XIOPlugBase, XIOPlugBase_iid)
